## Full UI Customization

In addition to customizing fields and theming, you can also provide a custom UI for one or more of the Authenticator steps.

For simple use cases (such as adding additional information), you can use a combination of default views from the **Authenticator** library and views that you define yourself:

```swift
Authenticator(
    signInContent: { state in
        HStack {
            Image("custom_image")
            Divider()
            SignInView(state: state) // Re-use the default SignInView
        }
    }
) { _ in
    // ...
}
```

For more complex cases, you can completely replace the UI for any particular step. 
Every view has an associated `*State` class that they observe, and that can be used to implement a custom UI.

This example shows how to fully replace the content displayed for the Sign In step:

```swift
Authenticator(
    signInContent: { state in
        CustomSignInView(state: state)
    }
) {
    // ...
}

/// Custom Sign In view
struct CustomSignInView: View {
    @ObservedObject var state: SignInState

    var body: some View {
        VStack {
            TextField("Username", text: $state.username)
            SecureField("Password", text: $state.password)
            Divider()

            Button("Sign in") {
                Task {
                    try? await state.signIn()
                }
            }

            if state.isBusy {
                ProgressView()
            }
        }
    }
}

```
